﻿Imports System.Drawing
Imports System.IO
Imports System.Text.RegularExpressions
Imports System.Threading

Imports _forms = System.Windows.Forms
Imports System.Windows.Interop
Imports System.Windows.Media.Effects
Imports Size = System.Drawing.Size



Class MainWindow
#Region "variables"
	Private Delegate Sub NoArgDelegate()

	Private ReadOnly Property Handle() As IntPtr
		Get
			Return New WindowInteropHelper(Me).Handle
		End Get
	End Property
	Private todoWatcher As FileSystemWatcher

	Private _notifyIcon As Forms.NotifyIcon

	Private ReadOnly Property TodoFileFullPath() As String
		Get
			If String.IsNullOrEmpty(_todoFilePath) Then
				_todoFilePath = Path.Combine(My.Settings.ToDoFilePath, My.Settings.ToDoFileName)
			End If

			Return _todoFilePath
		End Get
	End Property
	Private _todoFilePath As String
#End Region
#Region "form events"
	Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
		SetWindowLocation()
		Win32.HideFromAltTab(Handle)

		Width = SystemParameters.FullPrimaryScreenWidth
		Top = SystemParameters.FullPrimaryScreenHeight - Height + 22

		CreateNotifyIcon()
		VerifyToDoFileLocation()

		If File.Exists(TodoFileFullPath) Then
			fillWrapPanel()
		End If

		createFileSystemWatcher()
	End Sub

	Private Sub Window_StateChanged(ByVal sender As Object, ByVal e As EventArgs)
		If WindowState = WindowState.Minimized Then
			WindowState = WindowState.Normal
		End If
	End Sub

	Private Sub Window_IsVisibleChanged(ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
		If Visibility = Visibility.Visible Then
			SetWindowLocation()
		End If
	End Sub

	Sub openMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs)
		If Not File.Exists(TodoFileFullPath) Then
			File.Create(TodoFileFullPath).Close()
		End If

		Process.Start(TodoFileFullPath)
	End Sub

	Sub configurationMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs)
		Dim config = New Configuration With {.Owner = Me}

		Visibility = Visibility.Hidden

		' by showing the dialog, it thrusts the stuff to the front.
		config.ShowDialog()

		Visibility = Visibility.Visible
		fillWrapPanel()
	End Sub

	Sub exitToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs)
		_notifyIcon.Dispose()

		Close()
	End Sub

#End Region


#Region "private functions"
	Private Sub SetWindowLocation()
		If My.Settings.TopMost Then
			Win32.SetWindowInFront(Handle)
		Else
			Win32.SetWindowInBack(Handle)
		End If
	End Sub

	Private Sub CreateNotifyIcon()
		_notifyIcon = New _forms.NotifyIcon With {.Text = "ToDo", .Icon = New Icon("report.ico"), .Visible = True}

		Dim contextMenu = New Forms.ContextMenuStrip With {.Name = "contextMenu"}
		Dim exitToolStripMenuItem = New Forms.ToolStripMenuItem With {.Name = "exitToolStripMenuItem1", .Text = "Exit"}
		Dim configurationMenuItem = New Forms.ToolStripMenuItem With {.Name = "configurationMenuItem", .Text = "Options"}
		Dim openMenuItem = New Forms.ToolStripMenuItem With {.Name = "openMenuItem", .Text = "Open ToDo"}

		' contextMenu
		contextMenu.Items.AddRange(New Forms.ToolStripItem() {openMenuItem, configurationMenuItem, exitToolStripMenuItem})
		contextMenu.Size = New Size(155, 114)

		' exitToolStripMenuItem1
		exitToolStripMenuItem.Size = New Size(154, 22)
		AddHandler exitToolStripMenuItem.Click, AddressOf exitToolStripMenuItem_Click
		AddHandler configurationMenuItem.Click, AddressOf configurationMenuItem_Click
		AddHandler openMenuItem.Click, AddressOf openMenuItem_Click
		_notifyIcon.ContextMenuStrip = contextMenu
	End Sub

	Private Sub VerifyToDoFileLocation()
		If String.IsNullOrEmpty(My.Settings.ToDoFileName) OrElse String.IsNullOrEmpty(My.Settings.ToDoFilePath) Then
			My.Settings.ToDoFileName = "todo.txt"
			My.Settings.ToDoFilePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
			My.Settings.Save()
		End If

		If Not File.Exists(TodoFileFullPath) Then
			configurationMenuItem_Click(Me, Nothing)
		End If
	End Sub

	Private Sub createFileSystemWatcher()
		todoWatcher = New FileSystemWatcher With {.Path = My.Settings.ToDoFilePath, .Filter = My.Settings.ToDoFileName}

		AddHandler TodoWatcher.Changed, AddressOf todoWatcher_Changed
		AddHandler TodoWatcher.Created, AddressOf todoWatcher_Changed

		TodoWatcher.EnableRaisingEvents = True
	End Sub

	Private Sub todoWatcher_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs)
		wpTodo.Dispatcher.Invoke(New NoArgDelegate(AddressOf fillWrapPanel))
	End Sub

	Private Sub fillWrapPanel()
		' does file exist and not in use?
		Dim todoFileText As String = String.Empty

		If File.Exists(TodoFileFullPath) Then
			While FileInUse(TodoFileFullPath)
				Thread.Sleep(50)
			End While

			todoFileText = File.ReadAllText(TodoFileFullPath)
		End If

		wpTodo.Children.Clear()
		Dim items As String() = Regex.Split(todoFileText, Environment.NewLine)

		For Each item As String In items
			wpTodo.Children.Add(CreateLabel(item))
		Next
	End Sub

	Private Function CreateLabel(ByVal item As String) As Label

		Dim txt As New Label() With { _
		  .Background = New SolidColorBrush(System.Windows.Media.Color.FromArgb(0, 0, 0, 0)), _
		  .Foreground = New SolidColorBrush(My.Settings.FontForeColor), .AllowDrop = False, _
		  .Focusable = False, .BorderThickness = New Thickness(0), .Content = item}

		AddHandler txt.MouseDown, AddressOf txt_MouseDown

		If My.Settings.FontGlowColor.A <> 0 Then
			txt.BitmapEffect = New OuterGlowBitmapEffect() With {.GlowColor = My.Settings.FontGlowColor, .GlowSize = 7}
		End If

		Return txt
	End Function

	Sub txt_MouseDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
		SetWindowLocation()
	End Sub

	Public Shared Function FileInUse(ByVal path As String) As Boolean
		Try
			Using File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
				Return False
			End Using
		Catch ex As Exception
			If ex.Message.Contains("The process cannot access the file") Then
				Return True
			End If

			Throw
		End Try
	End Function
#End Region


End Class
